package ru.bytedog.oiot.counter.bot.controller.rest;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import ru.bytedog.oiot.counter.bot.bean.AppAuthority;
import ru.bytedog.oiot.counter.bot.bean.ErrorCode;
import ru.bytedog.oiot.counter.bot.dto.dashboard.CurrentUser;
import ru.bytedog.oiot.counter.bot.dto.dashboard.UserChangeRoleRequest;
import ru.bytedog.oiot.counter.bot.entity.BotUser;
import ru.bytedog.oiot.counter.bot.exception.ServiceException;
import ru.bytedog.oiot.counter.bot.service.UserService;

import java.util.UUID;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;

@ExtendWith(SpringExtension.class)
class UserControllerTest {

    @Mock
    UserService userService;

    @InjectMocks
    UserController controller;

    @Captor
    ArgumentCaptor<AppAuthority> captor;

    @Test
    void getUserInfo() {
        BotUser testUser = new BotUser();
        testUser.setUserName(getTestString());
        testUser.setFirstName(getTestString());
        testUser.setLastName(getTestString());
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(testUser, null, testUser.getAuthorities());

        CurrentUser user = controller.setUserRole(authentication);
        assertEquals(testUser.getUsername(), user.userName());
        assertEquals(testUser.getFirstName(), user.firstName());
        assertEquals(testUser.getLastName(), user.lastName());
    }

    @Test
    void setUserRole() throws ServiceException {
        UserChangeRoleRequest request = new UserChangeRoleRequest();
        request.setUsername(getTestString());
        request.setAdditional(true);
        doNothing().when(userService).changeRole(anyString(), captor.capture());
        controller.setUserRole(request);
        assertEquals(AppAuthority.ADMIN, captor.getValue());

        request.setAdditional(false);
        controller.setUserRole(request);
        assertEquals(AppAuthority.USER, captor.getValue());
    }

    @Test
    void setUserRoleWithException() {
        checkSetUserRoleException(null);
        checkSetUserRoleException(new UserChangeRoleRequest());
    }

    private String getTestString() {
        return UUID.randomUUID().toString();
    }

    private void checkSetUserRoleException(UserChangeRoleRequest request) {
        try {
            controller.setUserRole(request);
            fail();
        } catch (ServiceException e) {
            assertEquals(e.getErrorInfo(), ErrorCode.BAD_REQUEST);
        }
    }
}